package com.atom.module.coroutine.ext

import kotlin.coroutines.intrinsics.*
import kotlin.coroutines.intrinsics.intercepted

//
//    @file:kotlin.jvm.JvmName("IntrinsicsKt")
//    @file:kotlin.jvm.JvmMultifileClass
//    @file:Suppress("UNCHECKED_CAST")
//
//    package kotlin.coroutines.intrinsics
//
//    import kotlin.coroutines.*
//    import kotlin.coroutines.jvm.internal.*
//    import kotlin.internal.InlineOnly
//
//    /**
//     * Starts an unintercepted coroutine without a receiver and with result type [T] and executes it until its first suspension.
//     * Returns the result of the coroutine or throws its exception if it does not suspend or [COROUTINE_SUSPENDED] if it suspends.
//     * In the latter case, the [completion] continuation is invoked when the coroutine completes with a result or an exception.
//     *
//     * The coroutine is started directly in the invoker's thread without going through the [ContinuationInterceptor] that might
//     * be present in the completion's [CoroutineContext]. It is the invoker's responsibility to ensure that a proper invocation
//     * context is established.
//     *
//     * This function is designed to be used from inside of [suspendCoroutineUninterceptedOrReturn] to resume the execution of the suspended
//     * coroutine using a reference to the suspending function.
//     */
//    @SinceKotlin("1.3")
//    @InlineOnly
//    public actual inline fun <T> (suspend () -> T).startCoroutineUninterceptedOrReturn(
//        completion: Continuation<T>
//    ): Any? =
//        // Wrap with ContinuationImpl, otherwise the coroutine will not be interceptable. See KT-55869
//        if (this !is BaseContinuationImpl) wrapWithContinuationImpl(completion)
//        else (this as Function1<Continuation<T>, Any?>).invoke(completion)
//
//    // Work around private and internal visibilities of functions used: [createCoroutineFromSuspendFunction] and [probeCoroutineCreated].
//    @PublishedApi
//    internal fun <T> (suspend () -> T).wrapWithContinuationImpl(
//        completion: Continuation<T>
//    ): Any? {
//        val newCompletion = createSimpleCoroutineForSuspendFunction(probeCoroutineCreated(completion))
//        return (this as Function1<Continuation<T>, Any?>).invoke(newCompletion)
//    }
//
//    /**
//     * Starts an unintercepted coroutine with receiver type [R] and result type [T] and executes it until its first suspension.
//     * Returns the result of the coroutine or throws its exception if it does not suspend or [COROUTINE_SUSPENDED] if it suspends.
//     * In the latter case, the [completion] continuation is invoked when the coroutine completes with a result or an exception.
//     *
//     * The coroutine is started directly in the invoker's thread without going through the [ContinuationInterceptor] that might
//     * be present in the completion's [CoroutineContext]. It is the invoker's responsibility to ensure that a proper invocation
//     * context is established.
//     *
//     * This function is designed to be used from inside of [suspendCoroutineUninterceptedOrReturn] to resume the execution of the suspended
//     * coroutine using a reference to the suspending function.
//     */
//    @SinceKotlin("1.3")
//    @InlineOnly
//    public actual inline fun <R, T> (suspend R.() -> T).startCoroutineUninterceptedOrReturn(
//        receiver: R,
//        completion: Continuation<T>
//    ): Any? =
//        // Wrap with ContinuationImpl, otherwise the coroutine will not be interceptable. See KT-55869
//        if (this !is BaseContinuationImpl) wrapWithContinuationImpl(receiver, completion)
//        else (this as Function2<R, Continuation<T>, Any?>).invoke(receiver, completion)
//
//    // Work around private and internal visibilities of functions used: [createCoroutineFromSuspendFunction] and [probeCoroutineCreated].
//    @PublishedApi
//    internal fun <R, T> (suspend R.() -> T).wrapWithContinuationImpl(
//        receiver: R,
//        completion: Continuation<T>
//    ): Any? {
//        val newCompletion = createSimpleCoroutineForSuspendFunction(probeCoroutineCreated(completion))
//        return (this as Function2<R, Continuation<T>, Any?>).invoke(receiver, newCompletion)
//    }
//
//    @InlineOnly
//    internal actual inline fun <R, P, T> (suspend R.(P) -> T).startCoroutineUninterceptedOrReturn(
//        receiver: R,
//        param: P,
//        completion: Continuation<T>
//    ): Any? =
//        // Wrap with ContinuationImpl, otherwise the coroutine will not be interceptable. See KT-55869
//        if (this !is BaseContinuationImpl) wrapWithContinuationImpl(receiver, param, completion)
//        else (this as Function3<R, P, Continuation<T>, Any?>).invoke(receiver, param, completion)
//
//    // Work around private and internal visibilities of functions used: [createCoroutineFromSuspendFunction] and [probeCoroutineCreated].
//    @PublishedApi
//    internal fun <R, P, T> (suspend R.(P) -> T).wrapWithContinuationImpl(
//        receiver: R,
//        param: P,
//        completion: Continuation<T>
//    ): Any? {
//        val newCompletion = createSimpleCoroutineForSuspendFunction(probeCoroutineCreated(completion))
//        return (this as Function3<R, P, Continuation<T>, Any?>).invoke(receiver, param, newCompletion)
//    }
//
//    // JVM declarations
//
//    /**
//     * Creates unintercepted coroutine without receiver and with result type [T].
//     * This function creates a new, fresh instance of suspendable computation every time it is invoked.
//     *
//     * To start executing the created coroutine, invoke `resume(Unit)` on the returned [Continuation] instance.
//     * The [completion] continuation is invoked when coroutine completes with result or exception.
//     *
//     * This function returns unintercepted continuation.
//     * Invocation of `resume(Unit)` starts coroutine immediately in the invoker's call stack without going through the
//     * [ContinuationInterceptor] that might be present in the completion's [CoroutineContext].
//     * It is the invoker's responsibility to ensure that a proper invocation context is established.
//     * Note that [completion] of this function may get invoked in an arbitrary context.
//     *
//     * [Continuation.intercepted] can be used to acquire the intercepted continuation.
//     * Invocation of `resume(Unit)` on intercepted continuation guarantees that execution of
//     * both the coroutine and [completion] happens in the invocation context established by
//     * [ContinuationInterceptor].
//     *
//     * Repeated invocation of any resume function on the resulting continuation corrupts the
//     * state machine of the coroutine and may result in arbitrary behaviour or exception.
//     */
//    @SinceKotlin("1.3")
//    public actual fun <T> (suspend () -> T).createCoroutineUnintercepted(
//        completion: Continuation<T>
//    ): Continuation<Unit> {
//        val probeCompletion = probeCoroutineCreated(completion)
//        return if (this is BaseContinuationImpl)
//            create(probeCompletion)
//        else
//            createCoroutineFromSuspendFunction(probeCompletion) {
//                (this as Function1<Continuation<T>, Any?>).invoke(it)
//            }
//    }
//
//    /**
//     * Creates unintercepted coroutine with receiver type [R] and result type [T].
//     * This function creates a new, fresh instance of suspendable computation every time it is invoked.
//     *
//     * To start executing the created coroutine, invoke `resume(Unit)` on the returned [Continuation] instance.
//     * The [completion] continuation is invoked when coroutine completes with result or exception.
//     *
//     * This function returns unintercepted continuation.
//     * Invocation of `resume(Unit)` starts coroutine immediately in the invoker's call stack without going through the
//     * [ContinuationInterceptor] that might be present in the completion's [CoroutineContext].
//     * It is the invoker's responsibility to ensure that a proper invocation context is established.
//     * Note that [completion] of this function may get invoked in an arbitrary context.
//     *
//     * [Continuation.intercepted] can be used to acquire the intercepted continuation.
//     * Invocation of `resume(Unit)` on intercepted continuation guarantees that execution of
//     * both the coroutine and [completion] happens in the invocation context established by
//     * [ContinuationInterceptor].
//     *
//     * Repeated invocation of any resume function on the resulting continuation corrupts the
//     * state machine of the coroutine and may result in arbitrary behaviour or exception.
//     */
//    @SinceKotlin("1.3")
// TODO Common.runBlocking
//    public actual fun <R, T> (suspend R.() -> T).createCoroutineUnintercepted(
//        receiver: R,
//        completion: Continuation<T>
//    ): Continuation<Unit> {
//        val probeCompletion = probeCoroutineCreated(completion)  // 实际上直接将入参 当作 出参 返回了
//        return if (this is BaseContinuationImpl) // 初次调用不是BaseContinuationImpl 走 else
//            create(receiver, probeCompletion)
//        else {
//            createCoroutineFromSuspendFunction(probeCompletion) {
//                // 这里的this == Common.kt.runBlocking.函数执行体，虽然看着 两者差异很大，但在class层面，两者是统一相同的 可以被强转
//                // 执行Function2 的invoke函数 该函数会执行自身的create函数，将receiver, it==ContinuationImpl 传入并构造一个新的Function2
//                // 为何需要如此，因为字节码无法将指定的构造函数的参数 配置好，协程的为运行时动态的配置，因此需要将 CoroutineScope / Continuation 两个参数 动态的给定
//                // 最后返回并执行Function2.invokeSuspend 传入最初饿入参数Unit.INSTANCE
//                (this as Function2<R, Continuation<T>, Any?>).invoke(receiver, it)
//            }
//        }
//    }
//
//    /**
//     * Intercepts this continuation with [ContinuationInterceptor].
//     *
//     * This function shall be used on the immediate result of [createCoroutineUnintercepted] or [suspendCoroutineUninterceptedOrReturn],
//     * in which case it checks for [ContinuationInterceptor] in the continuation's [context][Continuation.context],
//     * invokes [ContinuationInterceptor.interceptContinuation], caches and returns the result.
//     *
//     * If this function is invoked on other [Continuation] instances it returns `this` continuation unchanged.
//     */
//    @SinceKotlin("1.3")
//    public actual fun <T> Continuation<T>.intercepted(): Continuation<T> =
//        (this as? ContinuationImpl)?.intercepted() ?: this
//
//    // INTERNAL DEFINITIONS
//
//    /**
//     * This function is used when [createCoroutineUnintercepted] encounters suspending lambda that does not extend BaseContinuationImpl.
//     *
//     * It happens in two cases:
//     *   1. Callable reference to suspending function,
//     *   2. Suspending function reference implemented by Java code.
//     *
//     * We must wrap it into an instance that extends [BaseContinuationImpl], because that is an expectation of all coroutines machinery.
//     * As an optimization we use lighter-weight [RestrictedContinuationImpl] base class (it has less fields) if the context is
//     * [EmptyCoroutineContext], and a full-blown [ContinuationImpl] class otherwise.
//     *
//     * The instance of [BaseContinuationImpl] is passed to the [block] so that it can be passed to the corresponding invocation.
//     */
//  TODO
//    @SinceKotlin("1.3")
//    private inline fun <T> createCoroutineFromSuspendFunction(
//        completion: Continuation<T>,
//        crossinline block: (Continuation<T>) -> Any?
//    ): Continuation<Unit> {
//        val context = completion.context
//        // label == 0 when coroutine is not started yet (initially) or label == 1 when it was
//        return if (context === EmptyCoroutineContext) // 如果是runBlocking 则走 else 如果是普通的launch 则走if==true
//            object : RestrictedContinuationImpl(completion as Continuation<Any?>) {
//                private var label = 0
//                override fun invokeSuspend(result: Result<Any?>): Any? =
//                    when (label) {
//                        0 -> {
//                            label = 1
//                            result.getOrThrow() // Rethrow exception if trying to start with exception (will be caught by BaseContinuationImpl.resumeWith
//                            block(this) // run the block, may return or suspend
//                        }
//                        1 -> {
//                            label = 2
//                            result.getOrThrow() // this is the result if the block had suspended
//                        }
//                        else -> error("This coroutine had already completed")
//                    }
//            }
//        else
//            object : ContinuationImpl(completion as Continuation<Any?>, context) { // runBlocking 走这个 返回这个匿名内部类
//                private var label = 0
//                override fun invokeSuspend(result: Result<Any?>): Any? =
//                    when (label) {
//                        0 -> {  // 开始label == 0 开始执行
//                            label = 1 // 设置为 1
//                            result.getOrThrow() // 判断之前的result是否存在异常 // Rethrow exception if trying to start with exception (will be caught by BaseContinuationImpl.resumeWith
//                            block(this) // 执行block 的内容 // run the block, may return or suspend
//                        }
//                        1 -> {
//                            label = 2
//                            result.getOrThrow() // this is the result if the block had suspended
//                        }
//                        else -> error("This coroutine had already completed")
//                    }
//            }
//    }
//
//    /**
//     * This function is used when [startCoroutineUninterceptedOrReturn] encounters suspending lambda that does not extend BaseContinuationImpl.
//     *
//     * It happens in two cases:
//     *   1. Callable reference to suspending function or tail-call lambdas,
//     *   2. Suspending function reference implemented by Java code.
//     *
//     * This function is the same as above, but does not run lambda itself - the caller is expected to call [invoke] manually.
//     */
//    private fun <T> createSimpleCoroutineForSuspendFunction(
//        completion: Continuation<T>
//    ): Continuation<T> {
//        val context = completion.context
//        return if (context === EmptyCoroutineContext)
//            object : RestrictedContinuationImpl(completion as Continuation<Any?>) {
//                override fun invokeSuspend(result: Result<Any?>): Any? {
//                    return result.getOrThrow()
//                }
//            }
//        else
//            object : ContinuationImpl(completion as Continuation<Any?>, context) {
//                override fun invokeSuspend(result: Result<Any?>): Any? {
//                    return result.getOrThrow()
//                }
//            }
//    }

///----------

/*
 * Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
 * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
 */


//    /**
//     * This probe is invoked when coroutine is being created and it can replace completion
//     * with its own wrapped object to intercept completion of this coroutine.
//     *
//     * This probe is invoked from stdlib implementation of [createCoroutineUnintercepted] function.
//     *
//     * Once created, coroutine is repeatedly [resumed][probeCoroutineResumed] and [suspended][probeCoroutineSuspended],
//     * until it is complete. On completion, the object that was returned by this probe is invoked.
//     *
//     * ```
//     * +-------+  probeCoroutineCreated +-----------+
//     * | START | ---------------------->| SUSPENDED |
//     * +-------+                        +-----------+
//     *                                      |   ^
//     *                probeCoroutineResumed |   | probeCoroutineSuspended
//     *                              +-------+   |
//     *                              |       |   |
//     *                              |       V   |
//     *                              |   +------------+ completion invoked  +-----------+
//     *                              +-- |   RUNNING  | ------------------->| COMPLETED |
//     *                                  +------------+                     +-----------+
//     * ```
//     *
//     * While the coroutine is resumed and suspended, it is represented by the pointer to its `frame`
//     * which always extends [BaseContinuationImpl] and represents a pointer to the topmost frame of the
//     * coroutine. Each [BaseContinuationImpl] object has [completion][BaseContinuationImpl.completion] reference
//     * that points either to another frame (extending [BaseContinuationImpl]) or to the completion object
//     * that was returned by this `probeCoroutineCreated` function.
//     *
//     * When coroutine is [suspended][probeCoroutineSuspended], then it is later [resumed][probeCoroutineResumed]
//     * with a reference to the same frame. However, while coroutine is running it can unwind its frames and
//     * invoke other suspending functions, so its next suspension can happen with a different frame pointer.
//     */
//    @SinceKotlin("1.3")
//    internal fun <T> probeCoroutineCreated(completion: Continuation<T>): Continuation<T> {
//        /** implementation of this function is replaced by debugger */
//        return completion
//    }
//
//    /**
//     * This probe is invoked when coroutine is resumed using [Continuation.resumeWith].
//     *
//     * This probe is invoked from stdlib implementation of [BaseContinuationImpl.resumeWith] function.
//     * Note, this probe can be invoked multiple times when coroutine is running. Every time the coroutine
//     * resumes a part its callstack that was previously stored in the heap, this probe is invoked
//     * with the references to the newly resumed [frame].
//     *
//     * Coroutines machinery implementation guarantees that the actual [frame] instance extends
//     * [BaseContinuationImpl] class, despite the fact that the declared type of [frame]
//     * parameter in this function is `Continuation<*>`. See [probeCoroutineCreated] for details.
//     */
// TODO
//    @SinceKotlin("1.3")
//    @Suppress("UNUSED_PARAMETER")
//    internal fun probeCoroutineResumed(frame: Continuation<*>) {
//        /** implementation of this function is replaced by debugger */
//    }
//
//    /**
//     * This probe is invoked when coroutine is suspended using [suspendCoroutineUninterceptedOrReturn], that is
//     * when the corresponding `block` returns [COROUTINE_SUSPENDED].
//     *
//     * This probe is invoked from compiler-generated intrinsic for [suspendCoroutineUninterceptedOrReturn] function.
//     *
//     * Coroutines machinery implementation guarantees that the actual [frame] instance extends
//     * [BaseContinuationImpl] class, despite the fact that the declared type of [frame]
//     * parameter in this function is `Continuation<*>`. See [probeCoroutineCreated] for details.
//     */
//    @SinceKotlin("1.3")
//    @Suppress("UNUSED_PARAMETER")
//    internal fun probeCoroutineSuspended(frame: Continuation<*>) {
//        /** implementation of this function is replaced by debugger */
//    }

